#include <vector>
#include <cstring>

#include <boost/static_assert.hpp>


#ifndef _KUAI_ARRAY_SLICE_H_
#define _KUAI_ARRAY_SLICE_H_

namespace kuai {


	template<typename OutputType, typename WordType>
		class ArraySlice
	{
	public:
		explicit ArraySlice() {
			_p0 = _pEnd = NULL;
			_inc = 1;
		};

		explicit ArraySlice(WordType buffer[], Size n, Size start = 0,  Size inc = 1) {
			_inc = inc;
			_p0 = buffer+start;
			_pEnd = _p0 + n*_inc;
		}

		explicit ArraySlice(ArraySlice& source, Size n, Size start=0, Size inc=1) {
			_inc = source._inc * inc;
			_p0 = source._p0 + start*_inc;
			_pEnd = _p0 + n*_inc;
		}


	public:
		size_t size() const {
			return (_pEnd-_p0)/_inc;
		}

		size_t isContinued() const {
			return sizeof(OutputType) == sizeof(WordType)*_inc;
		};

		OutputType& operator[](size_t index) {
			return *reinterpret_cast<OutputType*>(_p0+index*_inc);
		}
		const OutputType& operator[](size_t index) const {
			return *reinterpret_cast<const OutputType*>(_p0+index*_inc);
		}

		bool empty() const {
			return _p0 == _pEnd;
		}

		void zero() {
			if (isContinued()) {
				memset(_p0, 0, sizeof(WordType)*(_pEnd-_p0));
			}
			else {
				if (_inc > 0) {
					for (size_t i = 0; i < size(); ++i) {
						memset(_p0+i*_inc, 0, sizeof(OutputType));
					}
				}
				else if (!empty()) {
					memset(_p0, 0, sizeof(OutputType));
				}
			}
		}

		operator bool() const {
			return !empty();
		}

	private:
		WordType* _p0, *_pEnd;
		Size			_inc;

		BOOST_STATIC_ASSERT(sizeof(OutputType) % sizeof(WordType) == 0);
	};
}
#endif
